# coding=utf-8
"""
    将备份的脚本发布为 windows 服务
    !! 本机需安装 mysql client !!

正常流程 :
    1. 使用管理员身份打开命令行
    2. cd 到所在目录
    3.     python win_service.py install
    4.     python win_service.py start
    5.     python win_service.py stop
    6.     python win_service.py remove
    7. 打开 windows 服务, 找到该服务, 设置为开机自启动 ( 先点名称进行排序, 然后直接键盘敲: ginger 就找到了 )


异常情况 :
    执行 python win_service.py install 提示占用
        任务管理器, 搜索 pythonservice, 结束任务
        重新执行 python win_service.py install

    需要更改描述信息:
        停止服务, 重新执行 python win_service.py install, 服务中进行刷新即可

    其他我忘了, 哈哈哈, 反正就是停止服务, 删除服务啥的, 不行你把服务改成手动, 重启电脑重新来过, 再把服务改回自动
    多个服务时候, 有一个服务在运行时, 执行 python win_server install 会失败, 关了它即可 ( 因为 auto_teambition 也有 windows 服务 )
    多个服务时, 需要全都执行 install 之后, 再一个一个 start, 只要有一个先 install 后直接 start 的, 其他就无法 install ( 任务管理器删 ! )
"""

import schedule
import win32serviceutil
import win32service
import win32event
import servicemanager
import sys

from main.do_backup import *


# @Time    :  2024-06-05 17:34:37
# @Author  :  jiangtong
# @Email   :  gingerqgyy@outlook.com
# @Project :  mysql_backup
# @File    :  win_service


class BackupService(win32serviceutil.ServiceFramework):
    _svc_name_ = "GingerDatabaseBackupService"
    _svc_display_name_ = "Ginger Database Backup Service"
    _svc_description_ = f"A service that runs database backups every day at 7 AM."

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        sql_log.info('服务 windows service 初始化成功')
        self.running = True

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        sql_log.info('服务 windows service 停止运行')
        self.running = False

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_, ""))
        sql_log.info('服务 windows service 启动成功')
        self.main()

    def main(self):

        try:
            # 定时任务 : ( self.run_backup 中是启动新的线程执行, 这样不影响主线程持续轮询 )
            # schedule.every().day.at('07:00').do(self.run_backup)
            # 每周二早上七点执行 :
            schedule.every().tuesday.at('07:00').do(self.run_backup)
            while self.running:
                schedule.run_pending()
                time.sleep(1)
        except Exception as e:
            sql_log.error(f'运行遇到异常 : {e}')

    @staticmethod
    def run_backup():

        # 实际中, 每天早上七点备份测试数据库 : ( 自动化是七点之后运行, 我们在七点进行自动备份 )
        backup_thread = Thread(target=db_to_sql, args=(DB_INFO_H,))
        backup_thread.start()


if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(BackupService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(BackupService)
